package com.sojson.constant;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Set;

import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.ObjectName;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;

import com.sojson.util.ExpUtil;
import com.sojson.util.StringUtil;
import com.sojson.util.SystemParamBaseUtil;
import com.sojson.util.servlet.ServletUtil;

/**
 * 项目路径静态属性类
 *
 * @author liu
 * @date 2020-09-09
 */
public class IpConfig {

    /** 接口协议在缓存中的Key */
    private static String KEY_API_AGREEMENT = "api_agreement";
    /** 接口域名在缓存中的Key */
    private static String KEY_API_DOMAIN = "api_domain";
    /** 接口IP在缓存中的Key */
    private static String KEY_API_IP = "api_ip";
    /** 公网IP */
    private static String publicAddress;
    /** 端口号 */
    private static Short port;
    /** 上下文路径是否存在 */
    public static boolean contextPathIsExist;
    /** 上下文路径 */
    public static String contextPath;
    /** 上下文路径的长度 */
    public static int contextPathLength;

    static {
        // 初始化项目名称
        contextPath = Constant.PROPERTIES.getProperty("server.servlet.context-path");
        if (contextPath == null || contextPath.length() == 1) {
            contextPath = "";
        }
        contextPathIsExist = !"".equals(contextPath);
        contextPathLength = contextPath.length();
    }

    /**
     * 获取公网ip
     *
     * @return
     */
    public static String getPublicAddress() {
        if (publicAddress != null) {
            return publicAddress;
        }

        try {
            // 打开连接
            Document doc = Jsoup.connect("http://chaipip.com/").get();
            Elements eles = doc.select("#ip");
            publicAddress = eles.attr("value");
            return publicAddress;
        } catch (IOException e) {
            ExpUtil.throwEx(e);
            return null;
        }
    }

    /**
     * 获取本机ip
     *
     * @return
     */
    public static String getHostAddress() {
        String hostAddress = null;
        try {
            hostAddress = ServletUtil.getLocalHostIp();
        } catch (Exception e) {
            return null;
        }
        return hostAddress;
    }

    /**
     * 获取端口号
     *
     * @return
     */
    public static Short getPort() {
        if (port != null) {
            return port;
        }

        Short portStr = getPortByMbean();

        if (portStr == null) {
            portStr = Short.parseShort(Constant.PROPERTIES.getProperty("so.server.port"));
        }

        port = portStr;
        return port;
    }

    /**
     * 获取当前Tomcat实例的端口
     *
     * @return
     * @throws Exception
     */
    public static Short getPortByMbean() {
        Short portStr = null;
        MBeanServer mBeanServer = null;
        Set<ObjectName> objectNames = null;

        try {
            ArrayList<MBeanServer> mBeanServers = MBeanServerFactory.findMBeanServer(null);
            if (mBeanServers.size() > 0) {
                mBeanServer = mBeanServers.get(0);
            }
            if (mBeanServer == null) {
                // 没有发现JVM中关联的MBeanServer.
                return null;
            }

            objectNames = mBeanServer.queryNames(new ObjectName("Catalina:type=Connector,*"), null);
            if (objectNames == null || objectNames.size() <= 0) {
                // throw new Exception("没有发现JVM中关联的MBeanServer : " + mBeanServer.getDefaultDomain() + " 中的对象名称.");
                return null;
            }

            for (ObjectName objectName : objectNames) {
                String protocol = (String)mBeanServer.getAttribute(objectName, "protocol");
                if ("HTTP/1.1".equals(protocol)) {
                    portStr = isNotBlankObject(mBeanServer.getAttribute(objectName, "port"))
                        ? (Short)mBeanServer.getAttribute(objectName, "port") : portStr;
                    break;
                }
            }
        } catch (Exception e) {
            return null;
        }

        return portStr;
    }

    /**
     * 获取接口全路径
     *
     * @return
     * @throws Exception
     */
    public static String getUrl() throws Exception {
        String apiAgreement = SystemParamBaseUtil.getStr(KEY_API_AGREEMENT);
        String apiDomain = SystemParamBaseUtil.getStr(KEY_API_DOMAIN);
        return new StringBuilder(apiAgreement).append(apiDomain).append(IpConfig.contextPath).toString();
    }

    /**
     * 获取接口全路径
     *
     * @param ip
     * @return
     * @throws Exception
     */
    public static String getUrl(String ip) throws Exception {
        String apiAgreement = SystemParamBaseUtil.getStr(KEY_API_AGREEMENT);
        return new StringBuilder(apiAgreement).append(ip).append(":").append(getPort()).append(IpConfig.contextPath)
            .toString();
    }

    /**
     * 获取接口IP
     *
     * @return
     * @throws Exception
     */
    public static String getIp() throws Exception {
        return SystemParamBaseUtil.getStr(KEY_API_IP);
    }

    /**
     * 判断一个对象是否不是空(空对象)
     *
     * @param obj
     * @return
     */
    private static boolean isNotBlankObject(Object obj) {
        return StringUtil.isNotBlankObject(obj);
    }

}